/**
 * This class will implement the rate setting controller to our system. 
 * 
 * @author Gil Levinson
 * @author Boris Fradlis
 * @author Yogev Levi
 * @author Hila Porat
 */
package control;

// Imports ********************************************
import java.util.Timer;
import java.util.TimerTask;
import java.io.Serializable;
import java.util.Vector;

import javax.swing.JOptionPane;

import system.SystemMode;
import system.SystemTypes;
import system.VCP;
import system.VcpClient;
import vcpClasses.Notification;
import vcpClasses.ParkingLot;
import vcpClasses.User;

// Start of SetRatesController ***************************

public class MessageController extends AbstractController {
	
	//Class variables ***************************************

	private Vector<Notification> mVect = null;
	private int mVectCountBefore = 0;
	private int mVectCountAfter = 0;
	private boolean returned = false;
	private Timer timer = new Timer();
	private boolean notified = false;
	private SystemTypes sysType;
	
	/**
	 * Unimplemented constructor
	 */
	
	public MessageController(){};
	
	// Controller methods ****************************************************
	
	/**
	 * this method will check for new messages for the logged in user
	 * @param sysType - the user
	 * @return the vector of messages
	 */
	
	public Vector<Notification> GetMessages(SystemTypes sysType)
	{
		returned = false;
		
		if (mVect==null){
			mVectCountBefore=0;
		}
		else mVectCountBefore = mVect.size();
		
		boolean flag = SendToServer(sysType);
		while(!returned){}
		
		if (mVect==null){
			mVectCountAfter=0;
		}
		else mVectCountAfter = mVect.size();
		
		if (mVect!=null && notified==false && mVectCountAfter>mVectCountBefore){
			JOptionPane.showMessageDialog(null, "You have "+ (mVectCountAfter-mVectCountBefore) +" new message(s).", "Welcome",
	                JOptionPane.INFORMATION_MESSAGE);
			notified=true;
		}
		return mVect;
	}
	
	/**
	 * Timer implementation to check and get messages continuously 
	 * @param sysType - the user to check and get message for
	 * @return the vector of messages
	 */
	
	public Vector<Notification> TimedGetMessages(SystemTypes sysType){
		final Serializable temp = sysType.getObj();
		final SystemTypes help = new SystemTypes(temp,SystemMode.GET_MESSAGE);
		timer.scheduleAtFixedRate(new TimerTask() {
			  @Override
			  public void run() {
				  returned = false;
				  mVect=GetMessages(help);
			  }
			}, 1000, 30*1000);
		while(!returned){}		
		return mVect;
	}

	/**
	 * this method will mark a notification as read by the user.
	 * @param sysType - the notification to be marked as read.
	 * @return - an approval message that the notification was marked as read.
	 */
	
	public SystemTypes SetNotificationRead(SystemTypes sysType){
		returned = false;
		sysType.setSysMode(SystemMode.MARK_READ);
		boolean flag = SendToServer(sysType);
		while (!returned){}
		if (!flag)
		{
			switch (this.sysType.getSysMode())
			{
				case SYS_ERR:
				{
					this.sysType.setObj("Client - Server Connection Failed!");
					break;
				}
				case FAIL:
				{
					this.sysType.setObj("Lot were already initialized - process FAIL!");
					break;
				}
				case DB_CON_ERR:
				{
					this.sysType.setObj("DB connection Failed!");
					break;
				}
			default:
				this.sysType.setObj("Unknown failure in process!");
				break;
			}
		}
		else
			this.sysType.setObj("Message was marked as read !");
		return this.sysType;
	}
	
	@Override
	public boolean SendToServer(Serializable obj) {
		VCP.client.send(obj);
		if (((SystemTypes) obj).getObj() instanceof Notification)
		{
			sysType = (SystemTypes) VCP.client.getResult();
			if (sysType.getSysMode() != SystemMode.OK)
			{
				returned = true;
				return false;
			}
			returned = true;
			return true;
		}
		else{
			mVect = (Vector<Notification>) VCP.client.getResult();
			if (mVect != null)
			{
				returned = true;
				return false;
			}
			returned = true;
			return true;
		}
	}
	// Get and Set ***************************************************

		/**
		 * @return the returned
		 */
		public boolean isReturned() {
			return returned;
		}

		/**
		 * @param returned the returned to set
		 */
		public void setReturned(boolean returned) {
			this.returned = returned;
		}
	

}
